package edu.towson.greenteam;

import java.util.Observer;

import edu.towson.greenteam.menu.MenuItem;

import edu.towson.greenteam.menu.Price;

public class Simulation implements Runnable {

    static int currentClockTick;
    // cycle is needed to keep track of how many times clock tick has been reset
    // Using cycle, we can then calculate arrival times based on elapsed clock ticks
    // as in getCurrentClockTick() method
    static int cycle; 
    static int clockTickReset;
    static int customer_flow;
    static boolean running;
    static boolean exit;
    SystemInterface sys;
    
    //specific to simulation
    int tableCount = Consts.MAX_TABLES;
    int seatingCount = Consts.NUM_SEATS_PER_TABLE;
    int clockRate = Consts.CLOCK_RATE;
    
    int menuItemCount = 6;

    public Simulation() {
        cycle = 0;
        clockTickReset = 9000;
        currentClockTick = 0;
        customer_flow = 5;
        running = false;
        exit = false;
        sys = new SystemInterface();
        addTables();
        addMenuItems();
    }
    
    private void addMenuItems()
    {
    	//String name, String description, Price price, int maxQty, int prepTime
    	//apps
    	sys.i.getMenu().add(new MenuItem("Mozzerella Sticks", "Breaded, fried", new Price(5), 1000, 3));
    	sys.i.getMenu().add(new MenuItem("Loaded Fries", "Fried potatoes, bacon, cheese", new Price(6), 1000, 4));
    	sys.i.getMenu().add(new MenuItem("Chicken Wings", "Buffalo style", new Price(7), 1000, 5));
    	sys.i.getMenu().add(new MenuItem("Nacho", "Tortilla, nacho cheese, beans, etc.", new Price(8), 1000, 6));
    	//main
    	sys.i.getMenu().add(new MenuItem("Burger", "Plain meat on bun", new Price(9), 1000, 2));
    	sys.i.getMenu().add(new MenuItem("Turkey Club", "Turkey, cheese, mayo, bacon, lettuce, tomatoe", new Price(10), 1000, 3));
    	sys.i.getMenu().add(new MenuItem("Chicken Wrap", "Ceaser style, lettuce, tomatoe", new Price(11), 1000, 4));
    	sys.i.getMenu().add(new MenuItem("Fish Sandwich", "Haddock, fried, tartar", new Price(12), 1000, 5));
    	//dessert
    	sys.i.getMenu().add(new MenuItem("Ice Cream", "Vanilla", new Price(4), 1000, 1));
    	sys.i.getMenu().add(new MenuItem("Cake", "Chocolate", new Price(5), 1000, 2));
    	sys.i.getMenu().add(new MenuItem("Brownie Sundae", "Vanilla ice cream, chocolate brownie", new Price(6), 1000, 3));
    	sys.i.getMenu().add(new MenuItem("Peanut Butter Suprise", "We won't tell it's a suprise", new Price(7), 1000, 4));
    	
    }
    
    private void addTables()
    {
    	for(int i=0; i<tableCount; i++)
    	{
    		sys.i.getTables().add(seatingCount, false, 0);
    	}
    }

    public void begin() {
        running = true;
    }

    public void stop() {
        running = false;
    }

    @Override
    public void run() {
        try {
     	    while (!isExit()) {
	            if (running) {
	                currentClockTick++;
	                advanceSimulation();
	                if (currentClockTick == clockTickReset) {
	                    currentClockTick = 0;
                            cycle++;
	                }
	            }
	            // Pause the thread
	            Thread.sleep(clockRate);
    	    }     	    
        } catch (Exception e) {
            System.err.println("An error has occurred in the priority queue thread: " + e);
        }
    }

    public boolean isExit() {
		return exit;
	}

	public void setExit(boolean exit) {
		this.exit = exit;
	}

	public void advanceSimulation() {
    	sys.customersQueue.clockTick();
    	sys.i.getOrders().clockTick();
    }
	
	public void setObserver(Observer o) {
		try {
			sys.customersQueue.addObserver(o);
			sys.i.getOrders().addObserver(o);
			sys.i.getTables().addObserver(o);
		}
		catch (Exception e) {
			System.err.println(e);
		}
	}

        public static int getCurrentClockTick() {
            return cycle*clockTickReset + currentClockTick;
        }
    
}
